package cn.com.connected.base.utils;

import cn.com.connected.base.exception.BusinessException;
import cn.com.connected.base.exception.ErrorCode;
import cn.com.connected.base.params.page.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
public class BeanCopyUtils {

    /**
     * 创建过的BeanCopier实例放到缓存中，下次可以直接获取，提升性能
     */
    private static final Map<String, BeanCopier> BEAN_COPIERS = new ConcurrentHashMap<>();

    /**
     * 属性拷贝
     */
    public  static <T> T copy(final @NotNull Object srcObj, final @NotNull T destObj) {
        if (srcObj == null){
            return destObj;
        }
        String key = genKey(srcObj.getClass(), destObj.getClass());
        BeanCopier copier;
        if (!BEAN_COPIERS.containsKey(key)) {
            copier = BeanCopier.create(srcObj.getClass(), destObj.getClass(), false);
            BEAN_COPIERS.put(key, copier);
        } else {
            copier = BEAN_COPIERS.get(key);
        }
        copier.copy(srcObj, destObj, null);
//         BeanUtils.copyProperties(srcObj,destObj);
        return destObj;
    }

    public  static <T> List<T> copyList(List srcObjs,Class<T> destClass){
        List<T> results = new ArrayList();
        for (Object srcObj : srcObjs) {
            if (srcObj==null){
                continue;
            }
            T t = null;
            try {
                t = destClass.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                log.error(ExceptionUtils.getStackTrace(e));
                throw new BusinessException(ErrorCode.SYSTEM_FAIL);
            }
            copy(srcObj,t);
            results.add(t);
        }
        return results;
    }

    public  static <Z,T> PageResult<Z> copyPageResult(com.github.pagehelper.Page pageResult, Class<T> destClass) {
        PageResult pageResultDest  = new PageResult(pageResult);
        List resultData = pageResult.getResult();
        if (!CollectionUtils.isEmpty(resultData)){
            List destinationList  =  copyList(resultData,destClass);
            pageResultDest.setResultData(destinationList);
        }
        return pageResultDest;
    }

    private static String genKey(Class<?> srcClazz, Class<?> destClazz) {
        return srcClazz.getName() + destClazz.getName();
    }
}